'''
Created on 22.11.2012

@author: doleynik
'''
import time
import json
import webapp2
from webapp2_extras.i18n import gettext as _

from google.appengine.api import users
from apnetmodels.basicmodels import immeuble, invoice
from common import functions
from wtforms.ext.appengine.db import model_form
from wtforms.fields import TextField
from wtforms import validators

from BaseHandler import BaseHandler

class Invoices(BaseHandler):
    def __init__(self, *args, **kwargs):
        super(Invoices, self).__init__(*args, **kwargs)
        self.au = functions.GetAPNETUser()
        if not self.au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        self.fields = {'invoice_date': _('Invoice date'), 'immeuble': _('Tenement'), 'supplier': _('Supplier'),
                       'expendature': _('Expenditure'), 'charges_key': _('Charges key'), 'journal': _('Journal'),
                       'number': _('Document number'), 'title': _('Label'), 'amount': _('Amount TTC'), 'tva': _('VAT'),
                       'paid': _('Paid'), 'paid_amount': _('Paid amount'), 'rental_charges': _('Rental charges'),
                       'tax_deduction': _('Tax deduction'), 'property_income_deduction': _('Property income deduction'),
                       'bankaccount': _('Bank account'), 'amount_to_pay': _('To pay'), 'period': _('Acounting period'), 
                       'deadline': _('Deadline')
                       }
    
    def get(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)

    def post(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)

    def op_list(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        template_values = {
                           'title': _('Invoices. %s' % imm.name),
                           'header': _('%s. Invoices.' % imm.name),
                           'app_user': self.au,
                           'immeuble': imm,
                           'lurl': users.create_logout_url('/'),
                           'section': 'vie',
                           'leftmenu': 'invoice',
                           'fields': self.fields
                           }

        template = self.jinja2.get_template('templates/invoices_list.html')
        self.response.out.write(template.render(template_values))
    
    def op_add(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        ok_message = ''
        
        imm = immeuble.get_by_id(int(imm_id))
        
        InvoiceForm = model_form(invoice, exclude=['immeuble', 'paid', 'paid_amount', 'lastchange_by', 'closed', 'locked', 'pending_amount'])
        setattr(InvoiceForm, 'supplier', TextField(u'Supplier', [validators.required(),]))
        setattr(InvoiceForm, 'charges_key', TextField(u'Charges key', [validators.required(),]))
        setattr(InvoiceForm, 'expendature', TextField(u'Expenditure', [validators.required(),]))
        InvoiceForm.period.creation_counter = 1
        InvoiceForm.invoice_date.creation_counter = 10
        InvoiceForm.number.creation_counter = 15
        InvoiceForm.supplier.creation_counter = 20
        InvoiceForm.deadline.creation_counter = 25
        InvoiceForm.title.creation_counter = 30
        InvoiceForm.expendature.creation_counter = 40
        InvoiceForm.charges_key.creation_counter = 50
        InvoiceForm.amount.creation_counter = 60
        InvoiceForm.tva.creation_counter = 70
        InvoiceForm.rental_charges.creation_counter = 80
        InvoiceForm.tax_deduction.creation_counter = 90
        
        periods = []
        for p in imm.period_concept_set.filter('close_accounting =', False):
            periods.append(p)
            
        if self.request.method == 'GET':
            form = InvoiceForm()
            form['period'].query = periods
            form['supplier'].query = imm.syndic.supplier_set.order('contact')
            
        if self.request.method == 'POST':
            post_obj = self.request.POST
            
            s_list = imm.syndic.supplier_set.order('contact')
            exists = False
            for s in s_list:
                name = ''
                if s.contact.class_name() == 'person':
                    name = str(s.contact.first_name) + ' ' + str(s.contact.last_name) + ' (' + str(s.type_of_work) + ')'
                else:
                    name = str(s.contact.name) + ' (' + str(s.type_of_work) + ')'
                if name == post_obj['supplier']:
                    post_obj['supplier'] = s
                    exists = True
                    break
            if exists is False:
                post_obj['supplier'] = ''
            
            ck_list = imm.get_charges_key_list()
            exists = False
            for c in ck_list:
                if str(c) == post_obj['charges_key']:
                    post_obj['charges_key'] = c
                    exists = True
                    break
            if exists is False:
                post_obj['charges_key'] = ''
            
            exp_list = imm.get_exp_list()
            exists = False
            for e in exp_list:
                if str(e) == post_obj['expendature']:
                    post_obj['expendature'] = e
                    exists = True
                    break
            if exists is False:
                post_obj['expendature'] = ''
            
            form = InvoiceForm(post_obj)
            form['period'].query = periods
            if form.validate():
                new_invoice = invoice( 
                                      period = form['period'].data,
                                      invoice_date = form['invoice_date'].data, 
                                      supplier = form['supplier'].data,
                                      deadline = form['deadline'].data,
                                      number = form['number'].data,
                                      expendature = form['expendature'].data,
                                      charges_key = form['charges_key'].data,
                                      title = form['title'].data,
                                      amount = form['amount'].data,
                                      tva = form['tva'].data,
                                      rental_charges = form['rental_charges'].data, 
                                      tax_deduction = form['tax_deduction'].data,
                                      lastchange_by = self.au)
                
                new_invoice.put()
                while not new_invoice.is_saved():
                    time.sleep(2)
                
                ok_message = _('Invoice was added.')
            
            
        template_values = {'form': form, 'ok_message': ok_message, 'fields': self.fields}
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def op_edit(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        inv_id = kwargs.get('inv_id', -1)
        
        ok_message = ''
        
        imm = immeuble.get_by_id(int(imm_id))
        inv_obj = invoice.get_by_id(int(inv_id))
        if not inv_obj:
            self.object_does_not_exist()
            return
        
        InvoiceForm = model_form(invoice, exclude=['immeuble', 'paid', 'paid_amount', 'lastchange_by', 'closed','locked','pending_amount'])
        setattr(InvoiceForm, 'supplier', TextField(u'Supplier', [validators.required(),]))
        setattr(InvoiceForm, 'charges_key', TextField(u'Charges key', [validators.required(),]))
        setattr(InvoiceForm, 'expendature', TextField(u'Expenditure', [validators.required(),]))
        InvoiceForm.period.creation_counter = 1
        InvoiceForm.invoice_date.creation_counter = 10
        InvoiceForm.number.creation_counter = 15
        InvoiceForm.supplier.creation_counter = 20
        InvoiceForm.deadline.creation_counter = 25
        InvoiceForm.title.creation_counter = 30
        InvoiceForm.expendature.creation_counter = 40
        InvoiceForm.charges_key.creation_counter = 50
        InvoiceForm.amount.creation_counter = 60
        InvoiceForm.tva.creation_counter = 70
        InvoiceForm.rental_charges.creation_counter = 80
        InvoiceForm.tax_deduction.creation_counter = 90
        
        if self.request.method == 'GET':
            form = InvoiceForm(obj = inv_obj)
            form['supplier'].query = imm.syndic.supplier_set.order('contact')
            
        if self.request.method == 'POST':
            post_obj = self.request.POST
            
            s_list = imm.syndic.supplier_set.order('contact')
            exists = False
            for s in s_list:
                name = ''
                if s.contact.class_name() == 'person':
                    name = str(s.contact.first_name) + ' ' + str(s.contact.last_name) + ' (' + str(s.type_of_work) + ')'
                else:
                    name = str(s.contact.name) + ' (' + str(s.type_of_work) + ')'
                if name == post_obj['supplier']:
                    post_obj['supplier'] = s
                    exists = True
                    break
            if exists is False:
                post_obj['supplier'] = ''
            
            ck_list = imm.get_charges_key_list()
            exists = False
            for c in ck_list:
                if str(c) == post_obj['charges_key']:
                    post_obj['charges_key'] = c
                    exists = True
                    break
            if exists is False:
                post_obj['charges_key'] = ''
            
            exp_list = imm.get_exp_list()
            exists = False
            for e in exp_list:
                if str(e) == post_obj['expendature']:
                    post_obj['expendature'] = e
                    exists = True
                    break
            if exists is False:
                post_obj['expendature'] = ''
            
            form = InvoiceForm(post_obj)
            
            if form.validate():
                form.populate_obj(inv_obj)
                inv_obj.lastchange_by = self.au
                inv_obj.put()
                
                ok_message = _('Invoice was saved.')
        
        template_values = {'form': form, 'ok_message': ok_message, 'fields': self.fields}
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def op_list_4invoice_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        invs = []
        for p in imm.period_concept_set.filter('close_accounting =', False):  
            for i in p.invoice_set.filter('locked =', False).order('-invoice_date').run():
                invs.append([unicode(i.supplier), unicode(i.invoice_date), unicode(i), "%0.2f" % i.paid_amount, "%0.2f" % (i.amount - i.paid_amount), str(i.key().id()), i.title, "%0.2f" % i.amount])

        ret = {}
        ret['aaData'] = invs
        self.response.out.write(json.dumps(ret))

    def op_list_4payments_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        invs = []
        for p in imm.period_concept_set.filter('close_accounting =', False):  
            for i in p.invoice_set.filter('paid =', False).order('-invoice_date').run():
                invs.append([unicode(i.supplier), unicode(i.invoice_date), unicode(i), "%0.2f" % i.pending_amount, "%0.2f" % i.paid_amount, "%0.2f" % (i.amount - i.paid_amount), str(i.key().id()), i.title, "%0.2f" % i.amount])

        ret = {}
        ret['aaData'] = invs
        self.response.out.write(json.dumps(ret))

    def op_delete(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        inv_id = kwargs.get('inv_id', -1)
        
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        inv = invoice.get_by_id(int(inv_id))
        if not inv:
            self.object_does_not_exist()
            return
        
        ok_message = ''
        alert_message = ''
        
        if self.request.method == 'GET':
            alert_message = _('Are you sure you want to delete %s?' % inv)
            
        if self.request.method == 'POST':
            inv1 = inv
            inv.delete()
            while not inv1 is None:
                inv1 = invoice.get_by_id(int(inv_id))
                time.sleep(1)
            ok_message = _('Invoice was deleted.')
                
        template_values = {
            'ok_message': ok_message,
            'alert_message': alert_message,
            'fields': self.fields
        }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    